#include "rgsmaptoolselectionhandler.h"
#include<qgsmapcanvas.h>
#include<QDebug>

RgsMapToolSelectionHandler::RgsMapToolSelectionHandler(QgsMapCanvas *canvas, SelectionMode selectionMode)
    :mCanvas(canvas),mSelectionMode(selectionMode)
{

}

RgsMapToolSelectionHandler::~RgsMapToolSelectionHandler()
{
    mSelectionRubberBand.reset();
    mSelectionActive = false;
}

void RgsMapToolSelectionHandler::canvasMoveEvent(QgsMapMouseEvent *e)
{
    switch ( mSelectionMode )
    {
    case RgsMapToolSelectionHandler::SelectSimple:
        selectFeaturesMoveEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectPolygon:
        //selectPolygonMoveEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectFreehand:
        //selectFreehandMoveEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectRadius:
        //selectRadiusMoveEvent( e );
        break;
    }
}

void RgsMapToolSelectionHandler::canvasPressEvent(QgsMapMouseEvent *e)
{
    switch ( mSelectionMode )
    {
    case RgsMapToolSelectionHandler::SelectSimple:
        selectFeaturesPressEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectPolygon:
        selectPolygonPressEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectFreehand:
        break;
    case RgsMapToolSelectionHandler::SelectRadius:
        break;
    }
}

void RgsMapToolSelectionHandler::canvasReleaseEvent(QgsMapMouseEvent *e)
{
    switch ( mSelectionMode )
    {
    case RgsMapToolSelectionHandler::SelectSimple:
        selectFeaturesReleaseEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectPolygon:
        break;
    case RgsMapToolSelectionHandler::SelectFreehand:
        //selectFreehandReleaseEvent( e );
        break;
    case RgsMapToolSelectionHandler::SelectRadius:
        //selectRadiusReleaseEvent( e );
        break;
    }
}

void RgsMapToolSelectionHandler::initRubberBand()
{
    mSelectionRubberBand = std::make_unique<QgsRubberBand>( mCanvas, QgsWkbTypes::PolygonGeometry );
    mSelectionRubberBand->setFillColor( mFillColor );
    mSelectionRubberBand->setStrokeColor( mStrokeColor );
}

void RgsMapToolSelectionHandler::selectFeaturesPressEvent(QgsMapMouseEvent *e)
{
    if ( !mSelectionRubberBand )
        initRubberBand();

    mInitDragPos = e->pos();
}

void RgsMapToolSelectionHandler::selectFeaturesMoveEvent(QgsMapMouseEvent *e)
{
    if ( e->buttons() != Qt::LeftButton )
        return;

    QRect rect;
    if ( !mSelectionActive )
    {
        mSelectionActive = true;
        rect = QRect( e->pos(), e->pos() );
    }
    else
    {
        rect = QRect( e->pos(), mInitDragPos );
    }

    if ( mSelectionRubberBand )
        mSelectionRubberBand->setToCanvasRectangle( rect );
}

void RgsMapToolSelectionHandler::selectFeaturesReleaseEvent(QgsMapMouseEvent *e)
{
    const QPoint point = e->pos() - mInitDragPos;
    if ( !mSelectionActive || ( point.manhattanLength() < QApplication::startDragDistance() ) )
    {
        mSelectionActive = false;
        setSelectedGeometry( QgsGeometry::fromPointXY( toMapCoordinates( e->pos() ) ), e->modifiers() );
    }

    if ( mSelectionRubberBand && mSelectionActive )
        setSelectedGeometry( mSelectionRubberBand->asGeometry(), e->modifiers() );
    if ( mSelectionRubberBand )
        mSelectionRubberBand.reset();

    mSelectionActive = false;
}

void RgsMapToolSelectionHandler::selectPolygonPressEvent(QgsMapMouseEvent *e)
{
    if ( !mSelectionRubberBand )
        initRubberBand();
    if ( e->button() == Qt::LeftButton )
    {
        mSelectionRubberBand->addPoint( toMapCoordinates( e->pos() ) );
        mSelectionActive = true;
    }
    else
    {
        if ( mSelectionRubberBand->numberOfVertices() > 2 )
        {
            //setSelectedGeometry( mSelectionRubberBand->asGeometry(), e->modifiers() );
        }
        mSelectionRubberBand.reset();
        mSelectionActive = false;
    }
}

void RgsMapToolSelectionHandler::setSelectedGeometry(const QgsGeometry &geometry, Qt::KeyboardModifiers modifiers)
{
    mSelectionGeometry = geometry;
    qDebug()<<geometry.area();
    emit geometryChanged( modifiers );
}

QgsPointXY RgsMapToolSelectionHandler::toMapCoordinates(QPoint point)
{
    return mCanvas->getCoordinateTransform()->toMapCoordinates( point );
}

QgsGeometry RgsMapToolSelectionHandler::selectedGeometry()
{
    return mSelectionGeometry;
}
